From fd2f602c2f85944beb715559136f752a282b3836 Mon Sep 17 00:00:00 2001 From: Norbert Manthey Date: Mon, 28 Jan 2019 17:38:29 +0100 Subject: [PATCH] x86/CPUID: block speculative out-of-bound accesses During instruction emulation, the cpuid instruction is emulated with data that is controlled by the guest. As speculation might pass bound checks, we have to ensure that no out-of-bound loads are possible. To not rely on the compiler to perform value propagation, instead of using the array_index_nospec macro, we replace the variable with the constant to be propagated instead. This commit is part of the SpectreV1+L1TF mitigation patch series. Signed-off-by: Norbert Manthey Reviewed-by: Jan Beulich Release-acked-by: Juergen Gross --- xen/arch/x86/cpuid.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index 0591a7dc60..ab0aab678c 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -629,7 +630,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, if ( subleaf >= ARRAY_SIZE(p->cache.raw) ) return; - *res = p->cache.raw[subleaf]; + *res = array_access_nospec(p->cache.raw, subleaf); break; case 0x7: @@ -638,25 +639,25 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, ARRAY_SIZE(p->feat.raw) - 1) ) return; - *res = p->feat.raw[subleaf]; + *res = array_access_nospec(p->feat.raw, subleaf); break; case 0xb: if ( subleaf >= ARRAY_SIZE(p->topo.raw) ) return; - *res = p->topo.raw[subleaf]; + *res = array_access_nospec(p->topo.raw, subleaf); break; case XSTATE_CPUID: if ( !p->basic.xsave || subleaf >= ARRAY_SIZE(p->xstate.raw) ) return; - *res = p->xstate.raw[subleaf]; + *res = array_access_nospec(p->xstate.raw, subleaf); break; default: - *res = p->basic.raw[leaf]; + *res = array_access_nospec(p->basic.raw, leaf); break; } break; @@ -680,7 +681,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, ARRAY_SIZE(p->extd.raw) - 1) ) return; - *res = p->extd.raw[leaf & 0xffff]; + *res = array_access_nospec(p->extd.raw, leaf & 0xffff); break; default: @@ -847,7 +848,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, if ( is_pv_domain(d) && is_hardware_domain(d) && guest_kernel_mode(v, regs) && cpu_has_monitor && regs->entry_vector == TRAP_gp_fault ) - *res = raw_cpuid_policy.basic.raw[leaf]; + *res = raw_cpuid_policy.basic.raw[5]; break; case 0x7: -- 2.30.2